<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="referrer" content="origin">
    <!-- TDK and ICO -->
    <title>Tend to Code_一个使用django和bootstrap搭建的个人博客_TendCode</title>

    <meta name="description"
          content="TendCode是一个Django搭建的博客，本网站后端使用Django框架搭建，前端使用Bootstrap框架，主要分享博主在Python以及其他编程语言的学习心得。">
    <meta name="keywords" content="Python自学,Python爬虫,Django博客,Python web开发,个人博客">
    <!--站长验证-->

    <link rel="shortcut icon" href="/static/blog/img/favicon.ico" type="image/x-icon"/>
    <!-- Bootstrap and font-awesome CSS -->
    <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script src="/static/js/headroom.min.js"></script>
    <!-- blog CSS -->
    <link href="/static/css/base.css" rel="stylesheet">
    <link href="/static/css/detail.css?v=20190918.07" rel="stylesheet">
    <link href="/static/css/monokai.css?v=20190910.2" rel="stylesheet">
    <link href="/static/css/base_comment.css?v=20190114.554" rel="stylesheet">

    <!--根据cookies判断是否启用暗色主题-->

</head>
<body>
<!--导航开始-->

<nav class="navbar navbar-expand-md bg-white fixed-top blog-navbar py-md-0">
    <a class="navbar-brand d-md-none d-lg-block" id="site-logo-name" href="/">
        <strong class="px-2">TendCode</strong>
    </a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav ml-auto">
            <li class="nav-item mr-2">

                <a class="nav-link py-md-3 active" href="/"><i class="fa fa-home mr-1"></i>首页<span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item mr-2">

                <a class="nav-link py-md-3 " href="archive.html"><i class="fa fa-sitemap mr-1"></i>归档</a>
            </li>

            <li class="nav-item mr-2">

                <a class="nav-link py-md-3 " href="/tool/"><i class="fa fa-balance-scale mr-1"></i>在线工具</a>
            </li>


            <li class="nav-item mr-2 d-none d-lg-block">
                <a class="nav-link py-md-3" href="https://hao.tendcode.com" target="_blank"><i
                        class="fa fa-chrome mr-1"></i>微草导航</a>
            </li>


            <li class="nav-item mr-2 ">

                <a class="nav-link py-md-3 " href="/about/"><i class="fa fa-anchor mr-1"></i>关于</a>
            </li>
            <form class="nav-item navbar-form mr-2 py-md-2" role="search" method="get" id="searchform"
                  action="/search/">
                <div class="input-group">
                    <input type="search" name="q" class="form-control rounded-0" placeholder="站内搜索" autocomplete="off"
                           required=True>
                    <div class="input-group-btn">
                        <button class="btn btn-info rounded-0" type="submit"><i class="fa fa-search"></i></button>
                    </div>
                </div><!-- /input-group -->
            </form>
        </ul>
        <ul class="navbar-nav">

            <li class="nav-item mr-2">
                <a class="nav-link py-md-3" href="/accounts/login/?next=/">登录</a>
            </li>
            <li class="nav-item">
                <a class="nav-link py-md-3" href="/accounts/signup/?next=/">注册</a>
            </li>

        </ul>
    </div>
</nav>

<!--导航结束-->

<!--消息块-->


<!--回到顶部按钮-->
<div class="text-center" id="to-top">
    <i class="fa fa-chevron-up" id="btn-top" title="回到顶部"></i>
</div>

<!--主要内容块-->
<main>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-lg-9 col-xl-10">
                <nav aria-label="breadcrumb">
                    <ol class="breadcrumb bg-white border-0 rounded-0 mb-2 py-2 f-15">
                        <li class="breadcrumb-item">
                            <i class="fa fa-home mr-1"></i><a href="/">首页</a>
                        </li>
                        <li class="breadcrumb-item">
                            <a href="/category/Python-Web-development/">Python Web开发</a>
                        </li>
                        <li class="breadcrumb-item active d-none d-md-block" aria-current="page">博客将 Django 1.11+ 升级到 Django 2.2+ 遇到的问题及规避方法</li>
                        <li class="breadcrumb-item active d-md-none" aria-current="page">当前位置</li>
                    </ol>
                </nav>
                <div class="card rounded-0 border-0" id="article">
                    <div class="card-body px-2 px-md-3 pb-0">
                        <h1 class="card-title text-center font-weight-bold text-info">博客将 Django 1.11+ 升级到 Django 2.2+ 遇到的问题及规避方法</h1>
                        <hr>
                        <div class="text-center f-13">
                            <span class="mx-2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="最后编辑于2019年10月10日">2019年9月20日 00:36</span>
                            <span class="mx-2">阅读 702</span>
                            <a class="mx-2 to-com" href="#comment-block">评论 20</a>
                        </div>
                        <div class="article-body mt-4 f-17" style="line-height:1.8">
                            <p>之前就有人一直催我把博客的 Django 升级到 Django 2.0 以上，但是我一直懒得升级，因为我早就看过 Django 2.x 版本和 1.11.x 版本，其实没有太多的不同，所以没有找到需要升级的必要。但是，秉着向新技术看齐的态度，我还是花了些时间（大概半天）把博客依赖的 Django 升级到当前最新版的 Django 2.2.6 版本了，在升级的过程中也遇到了很多问题，这些问题也是之前考虑到的，所以基本都迎刃而解了，这篇文章就分享一下升级的过程。</p>
                            <h2 id="重装所有依赖库">重装所有依赖库</h2>
                            <p>为了升级 django 到 2.0 以上的版本，需要配套升级其他的依赖组件，所以需要把当前项目下面的 requirements.txt 文件里面依赖的版本号全部删除，然后重新创建一个虚拟环境，安装所有依赖的最新版本，这样就可以做到在使用 django2.0 的时候其他依赖组件也能支持 django。</p>
                            <h2 id="pymysql-版本报错">PyMySQL 版本报错</h2>
                            <h3 id="报错现象">报错现象</h3>
                            <p>将 Django 升级到 2.2 以上版本之后，会发现如下报错：</p>
                            <div class="codehilite"><pre><span></span>  <span class="o">...</span>

  <span class="nt">File</span> <span class="s2">"G:\envs\izone\lib\site-packages\django\db\backends\mysql\base.py"</span><span class="o">,</span> <span class="nt">line</span> <span class="nt">36</span><span class="o">,</span> <span class="nt">in</span> <span class="o">&lt;</span><span class="nt">module</span><span class="o">&gt;</span>
    <span class="nt">raise</span> <span class="nt">ImproperlyConfigured</span><span class="o">(</span><span class="s1">'mysqlclient 1.3.13 or newer is required; you have %s.'</span> <span class="o">%</span> <span class="nt">Database</span><span class="p">.</span><span class="nc">__version__</span><span class="o">)</span>
<span class="nt">django</span><span class="p">.</span><span class="nc">core</span><span class="p">.</span><span class="nc">exceptions</span><span class="p">.</span><span class="nc">ImproperlyConfigured</span><span class="o">:</span> <span class="nt">mysqlclient</span> <span class="nt">1</span><span class="p">.</span><span class="nc">3</span><span class="p">.</span><span class="nc">13</span> <span class="nt">or</span> <span class="nt">newer</span> <span class="nt">is</span> <span class="nt">required</span><span class="o">;</span> <span class="nt">you</span> <span class="nt">have</span> <span class="nt">0</span><span class="p">.</span><span class="nc">9</span><span class="p">.</span><span class="nc">3</span><span class="o">.</span>
</pre></div>


                            <p>这个问题的意思是需要 mysqlclient 1.3.13 以上版本，但是当前的版本是 0.9.3。之所以会出现这个问题，是因为 django 默认的 MySQL 连接库是 mysqldb，所以它其实想要读取的是这个库的版本，但是由于这个库不支持 Python3 所以我们一般会改成 pymysql 库来连接，所以这个地方就读取到了 PyMySQL 的版本是 0.9.3，因此版本号的要求就自然无法得到满足了。</p>
                            <h3 id="规避方法">规避方法</h3>
                            <p>方法一：将 Django 的版本降到 2.1.4 版本即可。</p>
                            <p>方法二：仍然使用 django 2.2+ 但是需要修改一些源码的代码。</p>
                            <p>首先需要修改报错的时候指定的文件（Django源码）：</p>
                            <div class="codehilite"><pre><span></span><span class="c1"># G:\envs\izone\lib\site-packages\django\db\backends\mysql\base.py</span>
<span class="c1"># 注释掉下面两行</span>

<span class="k">if</span> <span class="n">version</span> <span class="o">&lt;</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">):</span>
    <span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span><span class="s1">'mysqlclient 1.3.7 or newer is required; you have </span><span class="si">%s</span><span class="s1">.'</span> <span class="o">%</span> <span class="n">Database</span><span class="o">.</span><span class="n">__version__</span><span class="p">)</span>
</pre></div>


                            <p>网上说注释掉上面两行之后还会出现编码格式问题（我暂时没有发现），需要修改如下文件：</p>
                            <div class="codehilite"><pre><span></span><span class="c1"># G:\envs\izone\Lib\site-packages\django\db\backends\mysql\operations.py</span>
<span class="c1"># 修改 146 行</span>

<span class="k">if</span> <span class="n">query</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
    <span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">errors</span><span class="o">=</span><span class="s1">'replace'</span><span class="p">)</span>  <span class="c1"># decode 改为 encode</span>
<span class="k">return</span> <span class="n">query</span>
</pre></div>


                            <p>方法三：不要使用 PyMySQL 作为 MySQL 的连接库，而是使用官方推荐的 mysqlclient 作为依赖。因为这个库是支持 Python3 的，而且是官方推荐的库，可以避免出现问题。</p>
                            <p>由于修改了依赖，所以第一步应该卸载当前虚拟机环境中的 PyMySQL 库同时安装 mysqlclient 1.4.4，这个地方可能会出现问题，解决方式如下：</p>
                            <p>如果是 Windows 系统，直接使用 <code>pip install mysqlclient</code> 会报错，具体的报错还有原因可以自行上网搜索，这个时候应该选择下载 whl 文件的方式安装，具体的下载地址推荐 <a href="https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient">https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient</a></p>
                            <p>如果是 linux 系统，也可能出现问题，大概是缺少 MySQL 依赖，这个需要根据具体的系统版本去网上搜索依赖自行试试。</p>
                            <p>当依赖更换完毕之后，还需要修改项目配置（因为之前的项目配置中将 PyMySQL 设置成了默认的连接库，所以要删除掉），具体是删除如下两行，我的项目代码已经删除：</p>
                            <div class="codehilite"><pre><span></span><span class="c1"># 更换默认的数据库连接    </span>
<span class="kn">import</span> <span class="nn">pymysql</span>

<span class="n">pymysql</span><span class="o">.</span><span class="n">install_as_MySQLdb</span><span class="p">()</span>
</pre></div>


                            <h2 id="关于-on_delete-参数的报错">关于 on_delete 参数的报错</h2>
                            <h3 id="报错现象_1">报错现象</h3>
                            <div class="codehilite"><pre><span></span>    <span class="k">class</span> <span class="n">Article</span>(<span class="n">models</span>.<span class="n">Model</span>):
  <span class="n">File</span> <span class="s">"G:\Mycodes\izone\apps\blog\models.py"</span>, <span class="n">line</span> <span class="mi">71</span>, <span class="n">in</span> <span class="n">Article</span>
    <span class="n">author</span> = <span class="n">models</span>.<span class="n">ForeignKey</span>(<span class="n">settings</span>.<span class="n">AUTH_USER_MODEL</span>, <span class="n">verbose_name</span>=<span class="s">'作者'</span>)
<span class="n">TypeError:</span> <span class="n">__init__</span>() <span class="n">missing</span> <span class="mi">1</span> <span class="k">required</span> <span class="n">positional</span> <span class="n">argument:</span> <span class="s">'on_delete'</span>
</pre></div>


                            <p>报错的原因其实一看就能知道，这个地方是说的关于一些模型在一对一关联和一对多关联（外键）的时候需要指定 on_delete 参数才行，多对多没有这个设置。因为在 Django 1.x 的版本中，这个参数是有默认值的，但是 Django 2.x 没有指定，所以需要显示设定一个值。</p>
                            <h3 id="规避方法_1">规避方法</h3>
                            <p>把项目中所有模型中有外键的字段都添加这个属性，添加的时候需要根据实际情况设定值。</p>
                            <p>以下是主要的几个设置项的意义：</p>
                            <div class="codehilite"><pre><span></span><span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">,</span>     <span class="c1"># 删除关联数据,与之关联也删除</span>
<span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">DO_NOTHING</span><span class="p">,</span>  <span class="c1"># 删除关联数据,什么也不做</span>
<span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">PROTECT</span><span class="p">,</span>     <span class="c1"># 删除关联数据,引发错误ProtectedError</span>
<span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">SET_NULL</span><span class="p">,</span>    <span class="c1"># 删除关联数据,与之关联的值设置为null（前提该字段需要设置为可空,一对一同理）</span>
<span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">SET_DEFAULT</span><span class="p">,</span> <span class="c1"># 删除关联数据,与之关联的值设置为默认值（前提FK字段需要设置默认值,一对一同理）</span>
<span class="n">on_delete</span><span class="o">-</span><span class="n">models</span><span class="o">.</span><span class="n">SET</span><span class="p">(),</span>      <span class="c1"># 删除之后执行一个函数</span>
</pre></div>


                            <p>比如我这里添加了如下几个字段：</p>
                            <div class="codehilite"><pre><span></span><span class="c1"># class Article(models.Model):</span>
<span class="n">author</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">AUTH_USER_MODEL</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'作者'</span><span class="p">,</span>
    <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">PROTECT</span><span class="p">)</span>  <span class="c1"># 当删除有文章的作者时引发错误</span>
<span class="n">category</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Category</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'文章分类'</span><span class="p">,</span>
    <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">PROTECT</span><span class="p">)</span> <span class="c1"># 当删除有文章的分类时引发错误</span>

<span class="c1"># class ToolLink(models.Model):</span>
<span class="n">category</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">ToolCategory</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'网站分类'</span><span class="p">,</span>
    <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">SET_NULL</span><span class="p">)</span> <span class="c1"># 当工具分类删除后把分类设置为空</span>

<span class="c1"># class Comment(models.Model):</span>
<span class="c1"># 删除评论人或者父评论的时候同时删除评论</span>
<span class="n">author</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">AUTH_USER_MODEL</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s1">'</span><span class="si">%(class)s</span><span class="s1">_related'</span><span class="p">,</span>
    <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'评论人'</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>
<span class="n">parent</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="s1">'self'</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'父评论'</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s1">'</span><span class="si">%(class)s</span><span class="s1">_child_comments'</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
    <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>
<span class="n">rep_to</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="s1">'self'</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'回复'</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s1">'</span><span class="si">%(class)s</span><span class="s1">_rep_comments'</span><span class="p">,</span>
    <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>

<span class="c1">#class ArticleComment(Comment):</span>
<span class="n">belong</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Article</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s1">'article_comments'</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'所属文章'</span><span class="p">,</span>
    <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span> <span class="c1"># 提醒的文章被删除则删除提醒</span>

<span class="c1"># 省略其他修改项，都是根据实际情况添加设置</span>
</pre></div>


                            <h2 id="关于-urlspy-中-include-的报错">关于 urls.py 中 include() 的报错</h2>
                            <h3 id="报错现象_2">报错现象</h3>
                            <div class="codehilite"><pre><span></span>  <span class="nv">File</span> <span class="s2">"</span><span class="s">G:\envs\izone\lib\site-packages\django\urls\conf.py</span><span class="s2">"</span>, <span class="nv">line</span> <span class="mi">39</span>, <span class="nv">in</span> <span class="k">include</span>
    <span class="s1">'</span><span class="s">Specifying a namespace in include() without providing an app_name </span><span class="s1">'</span>
<span class="nv">django</span>.<span class="nv">core</span>.<span class="nv">exceptions</span>.<span class="nv">ImproperlyConfigured</span>: <span class="nv">Specifying</span> <span class="nv">a</span> <span class="nv">namespace</span> <span class="nv">in</span> <span class="k">include</span><span class="ss">()</span> <span class="nv">without</span> <span class="nv">providing</span> <span class="nv">an</span> <span class="nv">app_name</span> <span class="nv">is</span> <span class="nv">not</span> <span class="nv">supported</span>. <span class="nv">Set</span> <span class="nv">the</span> <span class="nv">app_name</span> <span class="nv">attribute</span> <span class="nv">in</span> <span class="nv">the</span> <span class="nv">inc</span>
<span class="nv">luded</span> <span class="nv">module</span>, <span class="nv">or</span> <span class="nv">pass</span> <span class="nv">a</span> <span class="mi">2</span><span class="o">-</span><span class="nv">tuple</span> <span class="nv">containing</span> <span class="nv">the</span> <span class="nv">list</span> <span class="nv">of</span> <span class="nv">patterns</span> <span class="nv">and</span> <span class="nv">app_name</span> <span class="nv">instead</span>.
</pre></div>


                            <p>报错分析，这个是 django 2.x 里面会出现的问题，当 urls.py 里面使用 include 的时候，当有 namespace 参数的时候，第一个参数需要添加成元组，其中第二个参数是 app_name。</p>
                            <h3 id="规避方法_2">规避方法</h3>
                            <p>首先，Django 2.x 跟 Django 1.x 最明显的修改就是在路由的格式，可以使用 path 替换之前使用的 url，会显得更简单，下面是我修改的：</p>
                            <div class="codehilite"><pre><span></span><span class="c1"># blog app 的写法</span>
<span class="n">path</span><span class="p">(</span><span class="s1">''</span><span class="p">,</span> <span class="n">include</span><span class="p">((</span><span class="s1">'blog.urls'</span><span class="p">,</span> <span class="s1">'blog'</span><span class="p">),</span> <span class="n">namespace</span><span class="o">=</span><span class="s1">'blog'</span><span class="p">)),</span>  <span class="c1"># blog</span>

<span class="c1"># restframework 的写法</span>
<span class="n">urlpatterns</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">path</span><span class="p">(</span><span class="s1">'api/v1/'</span><span class="p">,</span><span class="n">include</span><span class="p">((</span><span class="n">router</span><span class="o">.</span><span class="n">urls</span><span class="p">,</span> <span class="n">router</span><span class="o">.</span><span class="n">root_view_name</span><span class="p">),</span><span class="n">namespace</span><span class="o">=</span><span class="s1">'api'</span><span class="p">)))</span>
</pre></div>


                            <h2 id="redis-存储时序列化报错">redis 存储时序列化报错</h2>
                            <h3 id="报错现象_3">报错现象</h3>
                            <div class="codehilite"><pre><span></span><span class="n">PicklingError</span> <span class="k">at</span> <span class="o">/</span><span class="n">article</span><span class="o">/</span><span class="n">Jenkins</span><span class="o">-</span><span class="n">install</span><span class="o">/</span>
<span class="n">Can</span><span class="s1">'t pickle &lt;class '</span><span class="n">markdown</span><span class="p">.</span><span class="n">util</span><span class="p">.</span><span class="n">PriorityItem</span><span class="err">'</span><span class="o">&gt;</span><span class="p">:</span> <span class="n">attribute</span> <span class="n">lookup</span> <span class="n">PriorityItem</span> <span class="k">on</span> <span class="n">markdown</span><span class="p">.</span><span class="n">util</span> <span class="n">failed</span>
</pre></div>


                            <p>报错原因：由于我在把文章 markdown 转化之后就直接存放到 redis 中了，但是存储的时候序列化失败了（这个比较奇怪，之前没有遇到过）。</p>
                            <h3 id="规避方法_3">规避方法</h3>
                            <p>修改之后，我的代码如下：</p>
                            <div class="codehilite"><pre><span></span><span class="n">ud</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">update_date</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">"%Y%m</span><span class="si">%d</span><span class="s2">%H%M%S"</span><span class="p">)</span>
<span class="n">md_key</span> <span class="o">=</span> <span class="s1">'{}_md_{}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">ud</span><span class="p">)</span>
<span class="n">cache_md</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">md_key</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cache_md</span><span class="p">:</span>
    <span class="n">obj</span><span class="o">.</span><span class="n">body</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">toc</span> <span class="o">=</span> <span class="n">cache_md</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">md</span> <span class="o">=</span> <span class="n">markdown</span><span class="o">.</span><span class="n">Markdown</span><span class="p">(</span><span class="n">extensions</span><span class="o">=</span><span class="p">[</span>
        <span class="s1">'markdown.extensions.extra'</span><span class="p">,</span>
        <span class="s1">'markdown.extensions.codehilite'</span><span class="p">,</span>
        <span class="n">TocExtension</span><span class="p">(</span><span class="n">slugify</span><span class="o">=</span><span class="n">slugify</span><span class="p">),</span>
    <span class="p">])</span>
    <span class="n">obj</span><span class="o">.</span><span class="n">body</span> <span class="o">=</span> <span class="n">md</span><span class="o">.</span><span class="n">convert</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">body</span><span class="p">)</span>
    <span class="n">obj</span><span class="o">.</span><span class="n">toc</span> <span class="o">=</span> <span class="n">md</span><span class="o">.</span><span class="n">toc</span>
    <span class="c1"># 关键在这个地方，不能直接把 md 存进去</span>
    <span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">md_key</span><span class="p">,</span> <span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">body</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">toc</span><span class="p">),</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">12</span><span class="p">)</span>
</pre></div>


                            <h2 id="模板错误">模板错误</h2>
                            <p>模板报错都是和版本升级有关，因为我的博客重写了一些模板，所以升级版本必须同步到最新的模板去修改才行</p>
                            <p>下面这个报错是 bootstrap_admin 的模板被我改写了，所以报错，更新模板即可。</p>
                            <div class="codehilite"><pre><span></span>    <span class="ss">"or load this tag?"</span> <span class="o">%</span> <span class="p">(</span><span class="n">token</span><span class="p">.</span><span class="n">lineno</span><span class="p">,</span> <span class="n">command</span><span class="p">)</span>
<span class="n">django</span><span class="p">.</span><span class="k">template</span><span class="p">.</span><span class="n">exceptions</span><span class="p">.</span><span class="n">TemplateSyntaxError</span><span class="p">:</span> <span class="n">Invalid</span> <span class="n">block</span> <span class="n">tag</span> <span class="k">on</span> <span class="n">line</span> <span class="mi">14</span><span class="p">:</span> <span class="s1">'datetime_widget_css_path'</span><span class="p">.</span> <span class="n">Did</span> <span class="n">you</span> <span class="n">forget</span> <span class="k">to</span> <span class="n">register</span> <span class="k">or</span> <span class="k">load</span> <span class="n">this</span> <span class="n">tag</span><span class="o">?</span>
</pre></div>


                            <h2 id="升级mr">升级MR</h2>
                            <p>具体的修改MR可以看：<a href="https://github.com/Hopetree/izone/pull/76/files">https://github.com/Hopetree/izone/pull/76/files</a></p>
                            <p>后续补充MR：<a href="https://github.com/Hopetree/izone/pull/80/files">https://github.com/Hopetree/izone/pull/80/files</a></p>
                            <blockquote class="p-1 f-14" style="border-left: 4px solid #dc3545;">
                                <p class="m-1"><strong>版权声明：</strong>如无特殊说明，文章均为本站原创，转载请注明出处</p>
                                <p class="m-1"><strong>本文链接：</strong>https://tendcode.com/article/django2/</p>
                            </blockquote>
                        </div>
                        <div class="tag-cloud my-4">

                            <a class="tags f-16" href="/tag/Web-development/">后端开发</a>

                            <a class="tags f-16" href="/tag/Django/">Django</a>

                        </div>
                        <nav class="more-page f-16">
                            <ul class="pagination justify-content-between">
                                <li class="page-item">

                                    <a class="d-none d-md-block" href="/article/ansible-and-docker/" title="上一篇：使用 Ansible 工具批量操作虚拟机集群，自动化安装 Docker">
                                        <i class="fa fa-chevron-left mr-1"></i>
                                        使用 Ansible 工具批量操作虚
                                    </a>
                                    <a class="d-md-none" href="/article/ansible-and-docker/">
                                        <i class="fa fa-chevron-left mr-1"></i>上一篇</a>

                                </li>
                                <li class="page-item">

                                    <a class="d-none d-md-block" href="/article/python-shell-cmd/" title="下一篇：使用 python 执行 shell 命令的几种常用方式">
                                        使用 python 执行 shell
                                        <i class="fa fa-chevron-right ml-1"></i>
                                    </a>
                                    <a class="d-md-none" href="/article/python-shell-cmd/">
                                        下一篇<i class="fa fa-chevron-right ml-1"></i>
                                    </a>

                                </li>
                            </ul>
                        </nav>

                        <div class="text-center">
                            <button class="btn btn-danger rounded-0" data-toggle="collapse" data-target=".multi-collapse" aria-expanded="false" aria-controls="sponsor-zfb sponsor-wx" style="line-height: 1;font-size: .8rem;">
                                <i class="fa fa-cny"></i>
                                如果文章对你有所帮助，可以赞助本站
                                <i class="fa fa-chevron-down"></i>
                            </button>
                        </div>
                        <div class="row p-3">
                            <div class="col text-center">
                                <div class="collapse multi-collapse" id="sponsor-wx">
                                    <div class="p-1 text-success">微信</div>
                                    <img class="w-75" src="/static/blog/img/reward_wx.png">
                                </div>
                            </div>
                            <div class="col text-center">
                                <div class="collapse multi-collapse" id="sponsor-zfb">
                                    <div class="p-1 text-primary">支付宝</div>
                                    <img class="w-75" src="/static/blog/img/reward_zfb.png">
                                </div>
                            </div>
                        </div>
                    </div>

                </div>


            </div>
        </div>
    </div>
    <!--图片预览-->
    <div class="modal fade" id="img-to-big" tabindex="-1" role="dialog" aria-labelledby="img-to-bigTitle" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered" role="document" style="max-width: 90%">
            <img class="rounded mx-auto d-block" alt="image" style="max-width: 100%">
        </div>
    </div>
    <!--前后文章-->

    <div class="more-blog" id="icon-pre-blog">
        <a href="/article/ansible-and-docker/">
            <i class="fa fa-angle-left fa-3x"></i>
        </a>
    </div>


    <div class="more-blog" id="icon-next-blog">
        <a href="/article/python-shell-cmd/">
            <i class="fa fa-angle-right fa-3x"></i>
        </a>
    </div>

</main>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<!--js cookie 插件-->
<script src="/static/js/js.cookie.min.js?v=20191123.12"></script>
<script src="https://cdn.bootcss.com/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script>
    $(function () {
        var myElement = document.querySelector(".blog-navbar");
        var headroom = new Headroom(myElement);
        headroom.init()
    });
</script>
<script src="/static/js/base.js?v=20191123.0909890"></script>


<footer class="container-fluid mt-4 py-0">
    <div class="card-body text-center px-0 f-14">
        <p class="card-text mb-1">Copyright&nbsp;&copy;&nbsp;<span id="year-info"></span>
            &nbsp;Powered&nbsp;by&nbsp;Django.
        </p>


    </div>
</footer>
</body>
</html>